package com.wiscamp.ninechapters.panels.infrastructure.repositories;


import com.wiscamp.ninechapters.panels.domain.entities.Menu;
import com.wiscamp.ninechapters.panels.domain.repositories.MenuRepository;
import com.wiscamp.ninechapters.panels.infrastructure.converters.MenuConverter;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.MenuMapper;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.MenuViewMapper;
import com.wiscamp.ninechapters.panels.infrastructure.po.MenuPO;
import com.wiscamp.ninechapters.panels.infrastructure.views.MenuView;
import cube.ddd.aspect.HandleDataException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.PersistenceUtils;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public class MenuRepositoryImpl implements MenuRepository {

    private final MenuMapper menuMapper;

    private final MenuViewMapper menuViewMapper;

    public MenuRepositoryImpl(MenuMapper menuMapper, MenuViewMapper menuViewMapper) {
        this.menuMapper = menuMapper;
        this.menuViewMapper = menuViewMapper;
    }

    private MenuPO getMenuPO(long menuId) {
        return PersistenceUtils.findById(menuId, menuMapper::findById);
    }

    @HandleDataException
    public Menu getMenu(long menuId) {
        return PersistenceUtils.findEntityById(menuId, menuViewMapper::findById,
                MenuConverter.Instance::toMenuByView);
    }

    @HandleDataException
    public Menu getMenuByCode(long appId, String menuCode) {
        return PersistenceUtils.getEntityByIdAndText(appId, menuCode, menuViewMapper::findByMenuCode,
                MenuConverter.Instance::toMenuByView);
    }

    @HandleDataException
    public Collection<Menu> getMenusByGroup(long appId, String menuGroup) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, menuGroup, menuViewMapper::findListByMenuGroup,
                MenuConverter.Instance::toMenuByView);
    }

    @HandleDataException
    public Collection<Menu> getMenusByName(long appId, String menuName) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, menuName, menuViewMapper::findListByMenuName,
                MenuConverter.Instance::toMenuByView);
    }

    @HandleDataException
    public Collection<Menu> getMenusByIds(Collection<Long> menuIds) {
        return PersistenceUtils.getEntitiesByIds(menuIds, menuViewMapper::findAllById,
                MenuConverter.Instance::toMenuByView);
    }

    @HandleDataException
    public PagedObjects<Menu> getMenusByQuery(PagedQuery query) {
        PagedObjects<MenuView> pagedObjects = PersistenceUtils.getPersistenceObjectsByQuery(query, menuViewMapper::findAll);
        return PersistenceUtils.convertPagedObjects(pagedObjects, MenuConverter.Instance::toMenuByView);
    }

    @HandleDataException
    public Menu saveMenu(Menu menu) {
        if (menu.getMenuId() <= 0) {
            return PersistenceUtils.createEntity(menu, menuMapper::saveAndFlush,
                    MenuConverter.Instance::toMenuPO, MenuConverter.Instance::toMenu);
        } else {
            var existedPO = getMenuPO(menu.getMenuId());
            if (existedPO == null) existedPO = new MenuPO();
            return PersistenceUtils.updateEntity(menu, existedPO, menuMapper::saveAndFlush,
                    MenuConverter.Instance::toMenuPO, MenuConverter.Instance::toMenu);
        }
    }
}
